# util.py - some functions to handle reading in the game data from CSV files

import csv

# Fetch a CSV with game data and make a list of dicts out of it
def fetch_CSV(CSV_filename):
    result = []

    f = open(CSV_filename, 'rt')
    try:
        reader = csv.DictReader(f)
        for row in reader:
            result.append(row)
    finally:
        f.close()

    return result
    
# From the list of records of game data fetched above, fill the given class
# with keys for each record's name.  For example, if we've fetched the map
# buildings data, this will populate a class Building_Type that has a 
# field of the same name as each building found (Granary, Barracks, etc.)
def populate_type_class(class_to_populate, record_list, key_field):
    keys = map(lambda record: record[key_field], record_list)
    class_to_populate.__dict__.update(zip(keys, range(len(keys))))


# The techs spreadsheet has four fixed prereq tech slots; however, for ease
# of manipulation we want the prereqs in frozensets.  Further, the prereqs
# specified are only 'direct' prereqs, but we will want the set of all
# prereqs of prereqs as well, so we build that here too.
def build_tech_prerequisite_sets(tech_list):
    tech_dict = dict(zip(map(lambda t: t["Technology"], tech_list), tech_list))

    def all_prereq_techs(tech):
        this_tech_prereqs = tech["Prereq_Techs"]
        if len(this_tech_prereqs) == 0: return frozenset([])
        else:
            prereqs_of_prereqs = map(lambda p: all_prereq_techs(tech_dict[p]), 
                                     this_tech_prereqs)
            return this_tech_prereqs.union(*prereqs_of_prereqs)
            
    for tech in tech_list:
        tech["Prereq_Techs"] = frozenset(filter(lambda t: t != "",
            map(lambda i: tech["Prereq_Tech_" + str(i)], range(1, 5))
        ))
        
    for tech in tech_list:
        tech["All_Prereq_Techs"] = frozenset(all_prereq_techs(tech))


# Show the user a menu of things to be built (or incidentally, techs to be
# learned, since it also has the notion of a "Cost") and return the user's
# choice.  Boilerplate code that applies to units, wonders, buildings, etc.
def show_build_menu(available_build_items, item_key):
    for i in range(1, len(available_build_items) +1):
        item = available_build_items[i - 1]
        print str(i) + ".) " + item[item_key],
        print "(Cost: " + item["Cost"] + ")"
    print "0.) Go Back"
    return int(raw_input(
        "Choice [0-" + str(len(available_build_items)) + "]? "
    ))

